(function () {
    // 需要给外部库暴漏查询版本的接口用于升级
    // console.log(window.location.href)
    // "csp": "default-src 'self' blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'",

    /*
        let ws
        let wsInervalId
        const START_WS = true
        const WS_SERVER_URL = 'ws://localhost:24824/550eXUE8400eXUE29b41d4a6444uXUEiofnxc/20240718/'
        async function __createWebSocketConnection(url) {
            // https://www.npmjs.com/package/@tauri-apps/plugin-websocket?activeTab=code
            const WebSocket = window.__TAURI__.websocket;
            // D:\soft\rust\cargo\registry\src\rsproxy.cn-8f6827c7555bfaf8\tauri-2.0.6\src\ipc\channel.rs
            // 这里会创建一个channel
            const ws = await WebSocket.connect(url);
    
            function onmessage(event) {
                try {
                    //console.log("onmessage: %o", event)
                    if (!("object" == typeof event && "type" in event)) {
                        throw new Error(event)
                    }
                    let { data, type } = event
                    let str = data
    
                    if (type == 'Text') {
                        if (type == 'Text' && str.startsWith("{")) {
                            // console.log("收到消息: " + str)
                            let msgObj = JSON.parse(str)
                            let { Id, Success } = msgObj
                            let callback = SEND_MSG_PROMISE.get(Id)
                            if (callback) {
                                if (Success) {
                                    callback.ok(msgObj)
                                } else {
                                    callback.error(msgObj)
                                }
                            }
                        }
                        else if (str.startsWith("===========")) {
                            __closeWindow()
                        }
                    } else if (type == 'Pong') {
                        // 处理心跳
                    }
                } catch (e) {
                    ws.disconnect()
                    ws = null
                    // console.error("onmessage error:%o", e)
                }
            }
    
            ws.addListener((event) => { onmessage(event) });
    
            return ws
    
        }
        function __initWS() {
            if (START_WS) {
                wsInervalId = setInterval(function () {
                    //console.log("Interval out %o",ws)
                    try {
                        if (!ws) {
                            __createWebSocketConnection(WS_SERVER_URL)
                                .then((conn) => { ws = conn })
                                .catch((error) => {
                                    ws.disconnect()
                                    ws = null
                                    //console.log("Interval catch1: %o", error)
                                })
                        } else {
                            // 尝试ping
                            ws.send("Ping").catch(() => {
                                __createWebSocketConnection(WS_SERVER_URL)
                                    .then((conn) => { ws = conn })
                                    .catch((error) => {
                                        ws.disconnect()
                                        ws = null
                                        // console.log("Interval catch2: %o", error)
                                    })
                            })
                        }
                    } catch (e) {
                        ws.disconnect()
                        ws = null
                    }
                }, 5000)
            }
    
        }
    
    
    
    
    
    
        const SEND_MSG_PROMISE = new Map()
        function __sendWsMessage({ Id, Content }) {
            return new Promise(async (resolve, reject) => {
                try {
                    if (!ws || ws.id <= 0) {
                        ws = await __createWebSocketConnection(WS_SERVER_URL)
                    }
                    ws.send(Content)
                } catch (e) {
                    ws.disconnect()
                    ws = null
                    reject(Id + ' reject can not conn to ws  !!' + e);
                }
                //定时器
                const timeoutId = setTimeout(() => {
                    SEND_MSG_PROMISE.delete(Id)
                    // ws = null
                    reject(Id + ' reject timeout!!');
                }, 1000)
    
                //在 onmessage 中获取消息id 然后resolve,同时设置定时器防止超时
                SEND_MSG_PROMISE.set(Id, {
                    ok: (msgObj) => {
                        clearTimeout(timeoutId)
                        SEND_MSG_PROMISE.delete(Id)
                        // console.log(Id, "  resove")
                        // 返回结果
                        resolve(msgObj)
                    }
                    , error: (msgObj) => {
                        clearTimeout(timeoutId)
                        SEND_MSG_PROMISE.delete(Id)
                        // console.log(Id, "  reject")
                        reject(Id, " error reject")
                    }
    
                })
            })
        }
    
    


    let ws
    let wsInervalId
    const START_WS = false
    const WS_SERVER_URL = 'ws://localhost:24824/550eXUE8400eXUE29b41d4a6444uXUEiofnxc/20240718/'
    function __createWebSocketConnection(url) {
        ws = new WebSocket(url)
        ws.onopen = function (event) {
            console.log("WebSocket 连接已打开")
        }
        ws.onmessage = function (event) {
            let str = event.data
            //console.log("收到消息: " + str)
            try {
                if (str.startsWith("{")) {
                    let msgObj = JSON.parse(str)
                    let { Id, Success } = msgObj
                    let callback = SEND_MSG_PROMISE.get(Id)
                    if (callback) {
                        if (Success) {
                            callback.ok(msgObj)
                        } else {
                            callback.error(msgObj)
                        }
                    }
                }
                else if (str.startsWith("===========")) {
                    __closeWindow()
                }
            } catch (e) {
                console.error(e)
            }
        }
        ws.onclose = function (event) {
            console.log("WebSocket 连接已关闭")
        }
        ws.onerror = function (error) {
            console.error("WebSocket 出现错误:", error)
        }
        return ws

    }


    function __initWS() {
        if (START_WS) {
            ws = __createWebSocketConnection(WS_SERVER_URL)
            wsInervalId = setInterval(function () {
                // console.log("ws.readyState1:",ws.readyState)
                if (ws.readyState == WebSocket.OPEN) {
                    //console.log("ws.readyState:",ws.readyState)
                    //ws.send(jsonMsg("Hello, Server! " + (new Date().toISOString())))
                    ws.send('ping')
                } else if (ws.readyState != WebSocket.OPEN) {
                    ws = __createWebSocketConnection(WS_SERVER_URL)
                }
            }, 5000)
        }
    }


    const SEND_MSG_PROMISE = new Map()
    function __sendWsMessage11111111({ Id, Content }) {
        return new Promise((resolve, reject) => {

            try {
                if (ws.readyState != WebSocket.OPEN) {
                    ws = __createWebSocketConnection(WS_SERVER_URL)
                }
                ws.send(Content)
            } catch (e) {
                reject(Id + ' reject can not conn to ws  !!');
            }

            //定时器
            const timeoutId = setTimeout(() => {
                SEND_MSG_PROMISE.delete(Id)
                reject(Id + ' reject timeout!!');
            }, 1000)


            //在 onmessage 中获取消息id 然后resolve,同时设置定时器防止超时
            SEND_MSG_PROMISE.set(Id, {
                ok: (msgObj) => {
                    clearTimeout(timeoutId)
                    SEND_MSG_PROMISE.delete(Id)
                    //console.log(Id, "  resove")
                    // 返回结果
                    resolve(msgObj)
                }
                , error: (msgObj) => {
                    clearTimeout(timeoutId)
                    SEND_MSG_PROMISE.delete(Id)
                    //console.log(Id, "  reject")
                    reject(Id, " error reject")
                }

            })



        })
    }
*/

    async function __sendWsMessage({ Id, Content }) {
        let str = await _trySendMsg2Edog(Content)
        //console.log("收到消息1:%s" ,str)
        try {
            if(str){
                str=str.trim()
            }
            if (str.startsWith("{")) {
                let msgObj = JSON.parse(str)
                return msgObj
            } else if (str.startsWith("===========")) {
                __closeWindow()
            } 
        } catch (e) {
            console.error(e)
        }
    }


    function __jsonMsg(Content = "", Kind = "test") {
        let msg = {
            Id: new Date().getTime().toString(),
            Kind,
            Content
        }
        let str = JSON.stringify(msg)
        // console.log("__jsonMsg: ", str)
        return { Id: msg.Id, Content: str }
    }


    async function __checkScreen(x = 0, y = 0, w = 500, h = 500, check = true) {
        const { invoke } = window.__TAURI__.core
        let [success, time] = await invoke("check_screen", { x, y, w, h, check })
        // console.log("success:", success, " time:", time)
        return { success, time }
    }

    const callbackMap = new Map()
    // 注册事件回调
    async function addEventCallback(eventType, callback) {
        if (callbackMap.has(eventType)) {
            return new Error(`不能重复注册 ${eventType} 事件回调`);
        }
        if (callback) {

            let unlistenFn
            if ('close' === eventType) {
                unlistenFn = await __onCloseWindow(callback)
            } else {
                const { listen } = window.__TAURI__.event
                unlistenFn = await listen(eventType, (event) => {
                    (typeof callback === "function") && callback(event.payload)
                    //判断 eventType
                    if ('startRecording' == eventType) {
                        // 可以在回调时 给ws 发送消息使图标闪烁
                        __sendWsMessage(__jsonMsg(Content = "startRecording!" + (new Date().toISOString()), Kind = "startRecording"))
                    }
                })
            }
            callbackMap.set(eventType, unlistenFn)
        }
    }

    function removeEventCallback(eventType) {
        let unlistenFn = callbackMap.get(eventType);
        if (unlistenFn) {
            (typeof callback === "function") && unlistenFn()
        }
    }

    function __removeAllEventCallback() {
        //console.log("__removeAllEventCallback  %o",callbackMap)
        callbackMap.forEach(function (unlistenFn, _key) {
            (typeof callback === "function") && unlistenFn()
        })
    }

    async function __closeWindow() {
        const { getCurrentWindow } = window.__TAURI__.window
        await getCurrentWindow().close()
    }

    async function __onCloseWindow(callbackFn) {
        const { getCurrentWindow } = window.__TAURI__.window
        const { confirm } = window.__TAURI__.dialog
        const unlisten = await getCurrentWindow().onCloseRequested(async (event) => {
            const confirmed = await confirm('确定要关闭窗口?', '系统提示')
            const r = await callbackFn(confirmed)
            if (!r) {
                event.preventDefault()
            }
        });
        return unlisten
    }

    /// 是否正在录制
    async function isRecording() {
        const { invoke } = window.__TAURI__.core
        let isRecording = await invoke("is_recording")
        return isRecording
    }

    // let recordStatusChannel;
    //开始录屏
    async function startRecording(outputFile = "./output.mp4", watermarkText = '水印文字' /*, onRecordStatusCallback*/) {
        /*Channel 方式
        const { invoke, Channel } = window.__TAURI__.core
        const ids = new Uint32Array(1)
        window.crypto.getRandomValues(ids)
        const id = ids[0]
        recordStatusChannel = new Channel()
        let hasCallback=false
        if (onRecordStatusCallback) {
            recordStatusChannel.onmessage = onRecordStatusCallback
            hasCallback=true
        }
        let pid =  await invoke('start_recording', {
            id,
            outputFilename, watermarkText, hasCallback,
            recordStatusChannel
        })
        */
        const { invoke } = window.__TAURI__.core
        let pid = await invoke("start_recording", { outputFile, watermarkText /* ,hasCallback: !!onRecordStatusCallback*/ })
        // onStartRecording(onRecordStatusCallback)

        // 返回进程 pid >0 说明录屏进程已经启动,<=0 时 表示错误 
        return pid
    }

    async function validateChecksum(outputFile) {
        const { invoke } = window.__TAURI__.core
        const checksum = await invoke("validate_checksum", { outputFile })
        return checksum
    }

    //停止录屏
    // 如果没有错误的情况下会返回 checksum 字符串
    // 但是返回的 checksum 可能为null,这在多次调用这个函数时产生
    async function stopRecording() {
        const { invoke } = window.__TAURI__.core
        let checksum = await invoke("stop_recording")
        // __unlisten()
        // 如何销毁 onProgress Channel
        //recordStatusChannel=null;
        //alert(ok)
        return checksum
    }

    // 生成切屏比对模板
    async function checkScreenTemplate() {
        return await __checkScreen(5, 5, w = 50, h = 50, false)
    }
    // 检查是否切屏
    async function checkScreen() {
        return await __checkScreen()
    }

    // 全屏
    async function setFullscreen(enable = true) {
        const { getCurrentWindow } = window.__TAURI__.window
        await getCurrentWindow().setFullscreen(enable)
        await getCurrentWindow().setAlwaysOnTop(enable)
    }

    async function selectFile(multiple = false, suffix = ['mp4']) {
        const { open } = window.__TAURI__.dialog
        const file = await open({
            multiple,
            directory: false,
            filters: [{
                name: '文件',
                extensions: [...suffix]
            }]
        });
        return multiple ? file : [file]
    }

    async function selectPath(defaultPath) {
        let selectPath= defaultPath
        if (!selectPath) {
            const { desktopDir } = window.__TAURI__.path
            selectPath = await desktopDir()
        }

        const { open } = window.__TAURI__.dialog
        const selected = await open({
            directory: true,
            selectPath
        });
        if (Array.isArray(selected)) {
            // user selected multiple directories
            selectPath = selected[0]
        } else if (selected === null && !defaultPath) {
            // 取消选择且传入的 defaultPath 
            return defaultPath
        } else {
            // user selected a single directory
            selectPath = selected
        }
        return selectPath
    }

    /*
        //设置录屏保存路径当前路径
        //如果defaultPath 为空  ，则默认为为桌面
        //openSelectDialog 为true ，则打开选择对话框
        async function setSavePath(defaultPath, openSelectDialog = false) {
            if (!defaultPath) {
                const { desktopDir } = window.__TAURI__.path
                defaultPath = await desktopDir()
            }
    
            // 弹出选择框
            if (openSelectDialog) {
                defaultPath = await selectPath(defaultPath)
            }
    
            const { invoke } = window.__TAURI__.core
            let success = await invoke("set_save_path", { path: defaultPath })
            return defaultPath
        }
    */


    // 打开录屏保存位置
    async function openSavePath() {
        const { invoke } = window.__TAURI__.core
        let ok = await invoke("open_save_path")
        return ok
    }
    // 打开任意一个目录
    // 注意在windows 上目录必须是反斜杠
    // await openPath('d:\\')
    async function openPath(path) {
        const { invoke } = window.__TAURI__.core
        let ok = await invoke("open_path", { path })
        return ok
    }

    async function getSysinfo(path) {
        const { invoke } = window.__TAURI__.core
        let r = await invoke("get_sysinfo", { path })
        return r
    }

    async function pathExists(path) {
        const { invoke } = window.__TAURI__.core
        return await invoke("path_exists", { path })
    }

    // 启用键盘
    async function enableKeyboard(enable = true) {
        let r;
        if (enable) {
            r = await __sendWsMessage(__jsonMsg(Content = "stopHook!" + (new Date().toISOString()), Kind = "stopHook"))
        } else {
            r = await __sendWsMessage(__jsonMsg(Content = "startHook!" + (new Date().toISOString()), Kind = "startHook"))

        }
        return r.Success
    }

    // 获取虚拟桌面个数
    async function getDesktopCount() {
        let r = await __sendWsMessage(__jsonMsg(Content = "getDesktopCount!" + (new Date().toISOString()), Kind = "getDesktopCount"))
        return r.Content
    }

    /*
    // 杀死进程
    async function killProcess(ps = []) {
        if (ps.length > 0) {
            // 需要杀死的进程名称以分号分割
            let Content = ps.join(";")
            let r = await __sendWsMessage(__jsonMsg(Content, Kind = "killProcess"))
            let resultObj = {}
            r.Content.split(";").filter((kvstr) => null1 = kvstr).forEach((kvstr) => {
                let kv = kvstr.split(":")
                resultObj[kv[0]] = kv[1]
            });
            return resultObj
        }
    }
    */

    async function checkProcess(ps = [], isKill = false) {
        if (ps.length > 0) {
            // 需要检查的进程名称以分号分割
            let Content = ps.join(";")
            let Kind = isKill ? "killProcess" : "checkProcess"
            let r = await __sendWsMessage(__jsonMsg(Content, Kind))
            let resultObj = {}
            r.Content.split(";").filter((kvstr) => null1 = kvstr).forEach((kvstr) => {
                let kv = kvstr.split(":")
                resultObj[kv[0]] = kv[1]
            });
            return resultObj
        }
    }

    /// 检查环境,包括虚拟机和远程桌面
    async function checkEnv() {
        let r = await __sendWsMessage(__jsonMsg(Content = "checkEnv!" + (new Date().toISOString()), Kind = "checkEnv"))
        if (r.Success && r.Content == 'False') {
            const { message } = window.__TAURI__.dialog
            await message('本软件不支持在虚拟机或远程桌面中运行!', { title: '警告', type: 'error' });
            __closeWindow()
        }
        return true
    }



    async function upload(args /*,progressHandler*/) {
        /*
        const { invoke, Channel } = window.__TAURI__.core
        const ids = new Uint32Array(1);
        window.crypto.getRandomValues(ids);
        const id = ids[0];
        const onProgress = new Channel();
        if (progressHandler) {
            onProgress.onmessage = progressHandler;
        }
        return await invoke('upload', {
            id,
            args,
            onProgress
        });
        */

        const { invoke } = window.__TAURI__.core
        return await invoke('upload', { args });

    }

    /*
    async function download(url, filePath, progressHandler, headers) {
        const { invoke, Channel } = window.__TAURI__.core
        const ids = new Uint32Array(1);
        window.crypto.getRandomValues(ids);
        const id = ids[0];
        const onProgress = new Channel();
        if (progressHandler) {
            onProgress.onmessage = progressHandler;
        }
        await invoke('download', {
            id,
            url,
            filePath,
            headers: headers ?? {},
            onProgress
        });
    }
    */

    async function downloadPackage(args, /* progressHandler,*/ headers) {
        /*
        const { invoke, Channel } = window.__TAURI__.core
        const ids = new Uint32Array(1);
        window.crypto.getRandomValues(ids);
        const id = ids[0];
        const onProgress = new Channel();
        if (progressHandler) {
            onProgress.onmessage = progressHandler;
        }
        await invoke('download_package', {
            id,
            args,
            headers: headers ?? {},
            onProgress
        });
        */
        const { invoke } = window.__TAURI__.core
        await invoke('download_package', { args, headers: headers ?? {} })
    }

    //打包文件
    async function package(zipPath, filePath) {
        const { invoke } = window.__TAURI__.core
        return await invoke('package', { zipPath, filePath });
    }

    async function unpackage({ zipPath, destPath, password }) {
        const { invoke } = window.__TAURI__.core
        return await invoke('unpackage', { zipPath, destPath, password });
    }

    async function _trySendMsg2Edog(msg) {
        const { invoke } = window.__TAURI__.core
        return await invoke('try_send_msg_2_edog', { msg });
    }

    // async function startEdog() {
    //     const { invoke } = window.__TAURI__.core
    //     let ok = await invoke("start_edog")
    //     alert(ok)
    // }

    // async function stopEdog() {
    //     const { invoke } = window.__TAURI__.core
    //     let ok = await invoke("stop_edog")
    //     alert(ok)
    // }

    /// 获取桌面路径
    async function getDesktop() {
        const { desktopDir } = window.__TAURI__.path
        return await desktopDir()
    }


    async function __log(msg, level = 'info') {
        const { info, error } = window.__TAURI__.log
        if (level === 'error') {
            error(msg)
        } else {
            info(msg)
        }
    }

    async function logI(msg) {
        __log(msg)
    }

    async function logE(msg,) {
        __log(msg, level = 'error')
    }



    // 暴漏给客户端的api
    const APIX = {
        version: '20241018',
        startRecording, // U
        stopRecording,
        checkScreenTemplate,
        checkScreen,
        setFullscreen,

        // setSavePath,
        // openSavePath,

        openPath,
        selectPath,
        pathExists,
        selectFile,

        enableKeyboard,
        getDesktopCount,
        //killProcess,
        checkProcess,
        checkEnv,
        getSysinfo,

        addEventCallback,
        // removeEventCallback, 
        downloadPackage,
        upload,
        getDesktop,
        unpackage,
        logI,
        logE,
        isRecording,
        validateChecksum // +++
    }


    function __init_apix() {
       // __initWS()

        window.__TAURI__.APIX = APIX

        // 检查是否虚拟机
        //checkEnv()
    }


    window.onbeforeunload = function () {
        // console.log("========beforeunload")
        //clearInterval(wsInervalId)
        __removeAllEventCallback()
    }

    //=============================以上内容不要修改==================================

    document.addEventListener('DOMContentLoaded', function () { //window.onload
        // 注意此js 在每次加载不同的url 时 都会重新执行
        // console.log('init.js' + new Date())
        initWindowRightMenu()
        __init_apix()
    })


    // 测试用 初始化窗口右侧菜单
    function initWindowRightMenu() {

        let menu = document.createElement("div")
        menu.style = `
            background: wheat;
            position: fixed;
            z-index: 999;
            right: 0;
            top: 50%;
            transform: translate(0, -50%);`

        function creatMenuItem(html, clickFn) {
            let menuItem = document.createElement("div")
            menuItem.style = `
                cursor: pointer;
                margin:5px;
            `
            menuItem.innerHTML = html
            menuItem.onclick = clickFn
            menu.appendChild(menuItem)
        }

        creatMenuItem("进入全屏", async () => {
            await setFullscreen(true)
        })

        creatMenuItem("退出全屏", async () => {
            await setFullscreen(false)
        })

        creatMenuItem("开始录屏<span id='recordTimeSpan' ><span>", () => {

            // 开始录屏
            // startRecording("output", '薛')
            startRecording(`C:\\Users\\xueji\\Desktop\\test\\output1.mp4`, '薛1')
            // 注册回调函数
            addEventCallback('startRecording', (msg) => { document.getElementById("recordTimeSpan").textContent = msg })
        })

        creatMenuItem("停止录屏", async () => {
            let checksum = await stopRecording()
            console.log("checksum=%s", checksum)
            // alert(checksum)
        })

        creatMenuItem("生成模板", async () => {
            let { success } = await checkScreenTemplate()
            alert(success)
        })

        creatMenuItem("比对模板", async () => {
            let { success, time } = await checkScreen()
            alert(time + ' ' + success)
        })




        // creatMenuItem("设置录屏地址", async () => {
        //     await setSavePath('d:\\', true)
        // })
        creatMenuItem("打开目录", async () => {
            //await openSavePath()
            // 注意在windows 上目录必须是反斜杠
            await openPath('d:\\')
        })


        // creatMenuItem("startEdog", () => {
        //     startEdog()
        // })
        // creatMenuItem("stopEdog", async () => {
        //     stopEdog()
        // })


        creatMenuItem("禁用按键", async () => {
            // 注意发送参数的格式，可能导致 服务端解析不了
            let r = await enableKeyboard(false)
            alert(r)
        })
        creatMenuItem("启用按键", async () => {
            let r = await enableKeyboard()
            alert(r)
        })


        creatMenuItem("桌面个数", async () => {
            let r = await getDesktopCount()
            alert(r)
        })

        creatMenuItem("杀死进程", async () => {
            // 需要杀死的进程名称以分号分割
            // 进程的名称带不带exe 得经过测试
            let r1 = await checkProcess(["Notepad", "Notepad"])
            console.log("checkReuslt: %o", r1)
            let r2 = await killProcess(["Notepad", "Notepad"])
            console.log("killReuslt: %o", r2)

        })

        creatMenuItem("检查环境", async () => {
            let r = await checkEnv()
            alert(r)
        })


        creatMenuItem(`上传录屏:<span id="uploadProgress">0%</span>`, async () => {
            let args = {
                key: "0",
                // 上传文件本地全路径,可以用selectFile 函数获取
                srcFile: "E:/BaiduNetdiskDownload/01.高数基础/01新文道版本/31.第五章-定积分的应用.mp4",
                // 目的路径，参数需要在java端加密
                desPath: "/a/b/c/d",
                // 保存名称，参数需要在java端加密
                desFilename: "a.mp4",//，参数需要在java端加密
                // D:\soft\apache-ftpserver-1.2.0
                host: "localhost",//参数需要在java端加密
                port: 2121,//参数需要在java端加密
                username: "xue",//，参数需要在java端加密
                password: "123456",//参数需要在java端加密
            }

            let callback = ({ key, percent }) => {
                // console.log(`Uploaded ${percent} `)
                document.getElementById("uploadProgress").innerText = `key:${key}: ${percent}%`
            }

            upload(args).catch((error) => {
                alert(error)
            })

            //添加事件回调
            addEventCallback('upload', callback)

        })

        creatMenuItem(`下载文件:<span id="downloadProgress"></span>`, async () => {
            /* 下载单个文件
            download(
                'http://localhost:8081/a.mp4', //下载路径
                'd:/bbb.mp4'                //保存地址
                ,({fileIndex,status,percent}) => {
                    // console.log(`Uploaded ${percent} `)
                    document.getElementById("downloadProgress").innerText = `${percent}%`
                }
            ).catch((error) =>{
                alert(error)
            })
            */

            let args = {
                // 本地加密压缩包名称 ,废弃packageName
                // packageName:"考试1附件20241030",
                // 保存路径,可以用 selectPath 选择后传入
                // 要下载的文件列表
                files: [ // url 参数需要在java端加密
                    // key 要保证唯一 ,并且简短
                    // saveName 是保存文件的名称 ，savePath 保存路径
                    { key: "1", saveName: "a.mp4", savePath: "d:/a/b", url: "http://localhost:8081/a.mp4" }
                    , { key: "2", saveName: "b.mp4", savePath: "d:/a/b", url: "http://localhost:8081/a.mp4" }
                ]
            }
            //  fileIndex 指向 files 的索引 从0 开始
            //  status 状态,下载中,下载完成，打包完成
            //  percent 下载的百分比
            let callback = ({ key, status, percent }) => {
                let msg = `${key}-${status}-${percent}`
                //  console.log(msg)
                document.getElementById("downloadProgress").innerText = msg
            }

            downloadPackage(args)
            //添加事件回调
            addEventCallback('downloadPackage', callback)

            // __removeAllEventCallback()

        })

        creatMenuItem("选择文件并验证", async () => {
            const files = await selectFile()
            console.log("file: %o", files)

            const file = files[0]
            const checksum = await validateChecksum(file)

            alert(`file:${file},checksum:${checksum}`)
        })

        creatMenuItem("测试跳转index", async () => {
            window.location.href = "index.html"
        })
        creatMenuItem("测试跳转index1", async () => {
            window.location.href = "index1.html"
        })

        creatMenuItem("系统信息", async () => {
            // 获取系统信息包括磁盘剩余容量
            let r = await getSysinfo("d:/aaa")

            console.log(r)
            logI("这是日志")
            //检查路径或文件是否存在
            let r1 = await pathExists("d:\\aaa")

            console.log(r1)
        })


        creatMenuItem("测试解压", async () => {
            let args = {
                zipPath: "D:/a/b.zip",
                // 解压到路径,可以用 selectPath 选择后传入
                destPath: "d:/a/to",
                // 要下载的文件列表
                password: "123"
            }
            let r = await unpackage(args)
            alert(r)
        })

        creatMenuItem("添加关闭窗口监听", async () => {

            addEventCallback('close', async (confirmed) => {
                let canClose = false
                if (confirmed) {// 如果点击了确认按钮
                    canClose = true
                }
                // 返回true 表示关闭,false 表示阻止关闭
                return canClose
            })
        })


        document.body.appendChild(menu)
    }



})()